package com.ynqxg.router.processor

import com.google.devtools.ksp.processing.Dependencies
import com.google.devtools.ksp.processing.Dependencies.Companion.ALL_FILES
import com.google.devtools.ksp.processing.SymbolProcessorEnvironment
import com.google.devtools.ksp.symbol.KSClassDeclaration
import com.google.devtools.ksp.symbol.KSVisitorVoid
import java.io.OutputStream

class RouterKspVisitor(
    private val environment: SymbolProcessorEnvironment,
    private val callback: (String) -> Unit
) : KSVisitorVoid() {

    override fun visitClassDeclaration(classDeclaration: KSClassDeclaration, data: Unit) {
        val codeGenerator = environment.codeGenerator
        var fileOutputStream: OutputStream? = null
        try {
            val name: String? =
                classDeclaration.annotations
                    .find { it.shortName.asString() == Router::class.java.simpleName }
                    ?.arguments?.find {
                        it.name?.asString() == "value"
                    }?.value?.toString()
            // 写入注册语句
            val existPackageName = classDeclaration.packageName.asString()
            val existFileName = classDeclaration.simpleName.asString()
            val newFileName = "${existFileName}${RouterProcessor.ROOT_CLASS_NAME}"
            val packageName = "router.register.${environment.options["module"] ?: "app"}"
            callback("${packageName}.${newFileName}")
            // 生成router注册文件
            fileOutputStream = codeGenerator.createNewFile(
                ALL_FILES,
                packageName,
                newFileName
            ).also { outputStream ->
                outputStream.write("package $packageName\n".toByteArray())
                outputStream.write("\n".toByteArray())
                outputStream.write("import android.app.Activity\n".toByteArray())
                outputStream.write("import com.ynqxg.router.manager.RouterManager\n".toByteArray())
                outputStream.write("import ${existPackageName}.${existFileName}\n".toByteArray())
                outputStream.write("\n".toByteArray())
                outputStream.write("class $newFileName {\n".toByteArray())
                outputStream.write("\n".toByteArray())
                outputStream.write("   init {\n".toByteArray())
                outputStream.write("       RouterManager.putRouter( \"${name}\", ${existFileName}::class.java)\n".toByteArray())
                outputStream.write("   }\n".toByteArray())
                outputStream.write("\n".toByteArray())
                outputStream.write("}".toByteArray())
                outputStream.flush()
            }
            environment.logger.warn(newFileName)
        } catch (e: Exception) {
            if (e is FileAlreadyExistsException) {
                environment.logger.warn(e.localizedMessage)
            }
            e.printStackTrace()
        } finally {
            fileOutputStream?.close()
        }
    }

}